﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using YJKSparseDisOfDoor.ModelLayer;
using YJKInspectModelFunc.ModelLayer;

namespace YJKSparseDisOfDoor
{
	internal class Utility
	{
		public static DoorSchema GetDoorSchmaByDoorPacker(BaseDoorPacker input)
		{
			DoorSchema result = new DoorSchema();
			bool ifLinkedFileElement = input.IfLinkedFileElement;
			return result;
		}

		public static BaseRoomPacker GetDoorInRoomNoWayRoom(List<BaseRoomPacker> doorConnectRooms, BaseRoomPacker wayroom)
		{
			return (from k in doorConnectRooms
			where k.ThisElementPackerId != wayroom.ThisElementPackerId
			select k).First<BaseRoomPacker>();
		}

		public static bool GetRoomNameAndFloor(BaseRoomPacker inputroom, BaseDoorPacker intpudoor, ref string roomName, ref string floorName)
		{
			bool result;
			try
			{
				BaseRoomPacker doorInRoomNoWayRoom = Utility.GetDoorInRoomNoWayRoom(intpudoor.LstConctRooms, inputroom);
				if (doorInRoomNoWayRoom == null)
				{
					result = false;
				}
				else
				{
					Room thisRoom = doorInRoomNoWayRoom.ThisRoom;
					roomName = thisRoom.Name;
					floorName = thisRoom.get_Parameter(BuiltInParameter.ROOM_LEVEL_ID).AsValueString();
					result = true;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public static void ZoomEntiy(UIDocument useUIDoc, ResultBean useBean, ResultForm useForm, bool ifStartDoor)
		{
			Document document = useUIDoc.Document;
			ViewPlan viewPlan = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			FamilyInstance thisDoor;
			if (ifStartDoor)
			{
				thisDoor = useBean.StartDoor.ThisDoor;
			}
			else
			{
				thisDoor = useBean.EndDoor.ThisDoor;
			}
			Level level = document.GetElement(thisDoor.LevelId) as Level;
			List<int> list = new List<int>();
			ElementSet elementSet = new ElementSet();
			List<Element> list2 = new List<Element>();
			try
			{
				foreach (Element element in filteredElementCollector.OfClass(typeof(ViewPlan)))
				{
					ViewPlan viewPlan2 = (ViewPlan)element;
					if (viewPlan2 != null && viewPlan2.GenLevel != null && viewPlan2.GenLevel.Id.IntegerValue == level.Id.IntegerValue)
					{
						viewPlan = viewPlan2;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			try
			{
				if (viewPlan != null)
				{
					elementSet.Insert(thisDoor);
					list2.Add(thisDoor);
				}
			}
			catch (Exception)
			{
				list.Clear();
				elementSet.Clear();
				list2.Clear();
			}
			if (0 < list2.Count)
			{
				useUIDoc.ShowElements(elementSet);
				RevitVersionFuncs.SetSelection(useUIDoc.Selection, list2);
				useUIDoc.RefreshActiveView();
			}
		}

		public static bool TryGetAddedValue(Element input, out List<string> addedValue, out Entity usedEntity)
		{
			addedValue = new List<string>();
			Guid guid = new Guid("4F9061E6-11F5-4FA4-B5F6-B1913E19B439");
			Document document = input.Document;
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				Utility.CreatSchema(document, "4F9061E6-11F5-4FA4-B5F6-B1913E19B439");
			}
			Type typeFromHandle = typeof(InsertData);
			usedEntity = null;
			if (schema != null && schema.SchemaName.Equals("DoorSchema"))
			{
				Entity entity = input.GetEntity(schema);
				if (entity != null && entity.Schema != null)
				{
					foreach (FieldInfo fieldInfo in typeFromHandle.GetFields())
					{
						Field field = schema.GetField(fieldInfo.Name);
						if (fieldInfo.FieldType == typeof(List<string>))
						{
							usedEntity = entity;
							addedValue = entity.Get<IList<string>>(field).ToList<string>();
							return true;
						}
					}
				}
			}
			return false;
		}

		public static Schema CreatSchema(Autodesk.Revit.DB.Document doc, string schemaGuid)
		{
			Guid guid = new Guid(schemaGuid);
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				Transaction transaction = new Transaction(doc, "CreateSchema");
				try
				{
					transaction.Start();
					SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
					Type typeFromHandle = typeof(InsertData);
					schemaBuilder.SetSchemaName("DoorSchema");
					foreach (FieldInfo fieldInfo in typeFromHandle.GetFields())
					{
						if (fieldInfo.FieldType == typeof(List<string>))
						{
							schemaBuilder.AddArrayField(fieldInfo.Name, typeof(string));
						}
					}
					schema = schemaBuilder.Finish();
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
			return schema;
		}

		public static bool TryWriteToElement(Element input, InsertData inputValue)
		{
			Guid guid = new Guid("4F9061E6-11F5-4FA4-B5F6-B1913E19B439");
			Document document = input.Document;
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				Utility.CreatSchema(document, "4F9061E6-11F5-4FA4-B5F6-B1913E19B439");
			}
			Type typeFromHandle = typeof(InsertData);
			Transaction transaction = new Transaction(document, "WriteExtensibleStorage");
			List<string> lstInsetData = inputValue.m_lstInsetData;
			List<string> collection = new List<string>();
			Entity entity = null;
			if (Utility.TryGetAddedValue(input, out collection, out entity))
			{
				lstInsetData.AddRange(collection);
			}
			if (schema != null && schema.SchemaName.Equals("DoorSchema"))
			{
				if (entity == null)
				{
					entity = new Entity(schema);
				}
				try
				{
					transaction.Start();
					foreach (FieldInfo fieldInfo in typeFromHandle.GetFields())
					{
						Field field = schema.GetField(fieldInfo.Name);
						if (fieldInfo.FieldType.Name.Equals(typeof(List<string>).Name))
						{
							entity.Set<IList<string>>(field, lstInsetData.ToArray());
						}
					}
					input.SetEntity(entity);
					transaction.Commit();
					return true;
				}
				catch (Exception)
				{
					transaction.RollBack();
					return false;
				}
				return false;
			}
			return false;
		}

		private static void TryDeleteAddedRoom(Autodesk.Revit.DB.Document useDoc, List<int> addIds, out List<ElementId> lstElmenent, out Transaction useTransaction)
		{
			lstElmenent = new List<ElementId>();
			foreach (int num in addIds)
			{
				if (useDoc.GetElement(new ElementId(num)) != null)
				{
					lstElmenent.Add(new ElementId(num));
				}
			}
			useTransaction = new Transaction(useDoc, "DeleteRoom");
			useTransaction.Start();
			try
			{
				useDoc.Delete(lstElmenent);
				useTransaction.Commit();
			}
			catch (Exception)
			{
				useTransaction.RollBack();
			}
		}

		public static void AddValue(UIDocument useUIDoc, ResultForm useForm)
		{
			try
			{
				if (!useForm.IfManualEsc)
				{
					Document document = useUIDoc.Document;
					InsertData insertData = new InsertData();
					foreach (KeyValuePair<string, List<ResultBean>> keyValuePair in useForm.DicLstAllResult)
					{
						foreach (ResultBean resultBean in keyValuePair.Value)
						{
							insertData.m_lstInsetData.Clear();
							if (useForm.NeedTrustData.Contains(resultBean.GetHashCode()))
							{
								DoorSchema doorSchema = new DoorSchema(resultBean.StartDoor.ThisDoor.Id, resultBean.EndDoor.ThisDoor.Id, resultBean.Distance);
								insertData.m_lstInsetData.Add(doorSchema.ThisValue);
								if (resultBean.StartDoor.UseRevitLinkInstance == null)
								{
									Utility.TryWriteToElement(resultBean.StartDoor.ThisDoor, insertData);
								}
								else
								{
									Utility.TryWriteToElement(resultBean.StartDoor.UseRevitLinkInstance, insertData);
								}
								if (resultBean.EndDoor.UseRevitLinkInstance == null)
								{
									Utility.TryWriteToElement(resultBean.EndDoor.ThisDoor, insertData);
								}
								else
								{
									Utility.TryWriteToElement(resultBean.EndDoor.UseRevitLinkInstance, insertData);
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private const string GRID_GUID = "4F9061E6-11F5-4FA4-B5F6-B1913E19B439";
	}
}
